#ifndef HEAD_H
#define  HEAD_H

#include <my_header.h>
#include <crypt.h>
#include "workqueue.h"
#include <errno.h>

#define MAX_STACK_SIZE 100

// 功能：响应报错信息
#define RETERROR1() do {char buf[1024] = {0}; strerror_r(errno,buf,sizeof(buf)); TLVResponse(user->sockfd,buf,IS_NOT_OK);} while(0)

// 功能：响应报错信息
#define RETERROR2(expected) do {char buf[] = expected; TLVResponse(user->sockfd,buf,IS_NOT_OK);} while(0)

// 功能：响应通过
#define RETOK(expected) do {char buf[] = expected; TLVResponse(user->sockfd,buf,IS_OK);} while(0)





// 用于填充TLV协议的T部分

enum{
    CD,
    LS,
    PUTS,
    GETS,
    PWD,
    MKDIR,
    RMDIR,
    REMOVE,
    FILE_LEN,
    SEND_FILE,
    CANCEL,
    IS_OK,
    IS_NOT_OK,
    LOGIN_NAME,// 用户名
    LOGIN_PASSWORD,// 用户密码
};

// 传输格式
typedef struct train_s{
    int type;
    bool args[4];
    int len;
    char path[1024];
}train_t;

// 用户相关信息
typedef struct user_s{
    int sockfd;
    char usercur[1024];
    int depth;
    int slash[MAX_STACK_SIZE];
    char username[20];
}user_t;




// 线程id表
typedef struct tidArrS{
    int *workerPid;
    int len;
}tidArrT;
// 线程池
typedef struct threadPoolS{
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    workqueue_t *workQueue;
    tidArrT tidArr;
}threadPoolT;


int acceptOrder(user_t *user);

//  
int simPath(char *originalPath, char *curPath, int *pDepth, int *slash, user_t *user);
int CDOrder(user_t *user, char *newPath, int *newSlash, int newDepth);
int LSOrder(user_t *user, char *destPath, bool *args);
int PUTSOrder(user_t *user, char *destPath);
int GETSOrder(user_t *user, char *destPath);
int MKDIROrder(user_t *user, char *destPath);
int RMDIROrder(user_t *user, char *destPath, bool *args);
int RMDIR_ROrder(user_t *user, char *destPath);
int REMOVEOrder(user_t *user, char *destPath);
int PWDOrder(user_t *user);

int TLVResponse(int sockfd, char *buf, int type);

int recvFile(user_t *user, int fd, int offset, int fileSize);
int sendFile(user_t *user, int fd, int offset, int fileSize);
int ls_l(char *buf, int size, struct dirent *entry);




// 功能：创建监听SOCKET并监听
// 返回值：监听socket的值
int establishConnect(char *ip, char *port);

int epollAdd(int efd, int monitorfd);

int epollDel(int efd, int delfd);

// 功能：连接开始时，监听客户端发送的用户名密码，并进行校验，
// 参数：
//      sockfd：与客户端进行通信的socket
// 返回：
//      -1：连接出错，客户端断开连接
//      0：表示身份校验成功
//      1：用户名错误
//      2：密码错误
int loginVerify(int sockfd, char *userName);


// 功能：创建线程池
// 参数：
//      pool：传入传出参数
//      workerCount：需要线程数
// 返回值：
//      0：表示成功
int makeThreadPool(threadPoolT *pool, int workerCount);

// 功能：返回给客户端的响应
// 参数：
//      sockfd：与客户端进行通信的socket
//      buf：传入参数，需要传送给客户端的信息
//      is_ok: 状态信息，枚举中的值
// 返回值：
//      0：表示发送成功
/* int TLVResponse(int sockfd, char *buf, int is_ok); */

// 功能：文件传输时，向客户端响应一个长度
int TLVResponseLen(int sockfd, int len, int type);

// 功能：与客户端进行交互的逻辑
int interactWithTheClient(int sockfd);


// 功能：获取指令
int getInstruction(int sockfd, train_t *train);

// 功能：获取TLV的前两个字段
int getTL(int sockfd, train_t *train);

#endif
